package com.cloudlead.common.worker.interceptor;

import com.cloudlead.common.worker.ActionContext;
import com.cloudlead.common.worker.Interceptor;
import com.cloudlead.common.worker.InterceptorChain;
import com.cloudlead.common.worker.annotation.Order;
import com.cloudlead.common.worker.annotation.Provider;
import com.cloudlead.common.lang.api.AbstractActionResponse;
import com.cloudlead.common.lang.api.ActionResponse;
import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

/**
 * 日志拦截器
 *
 * @author dean.lu
 */
@Provider
@Order(1)
public class LoggerInterceptor implements Interceptor {
    private static final Logger LOGGER = LoggerFactory
            .getLogger(LoggerInterceptor.class);

    @Override
    public void intercept(ActionContext actionConfig, InterceptorChain chain) throws Exception{

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        MDC.put("action.name", actionConfig.getActionName());
        MDC.put("request.id", actionConfig.getRequest().getRequestId());

        LOGGER.debug(String.format("==> invoke api [%s] start , request is : %s ",
                actionConfig.getActionName(), actionConfig.getRequest()));
        try {
            chain.process(actionConfig);
            LOGGER.debug(String.format("<== invoke api [%s] success , response is : %s ",
                    actionConfig.getActionName(), actionConfig.getResponse()));
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error(String.format(
                    "<!= invoke api [%s] error , throwed exception is : ",
                    actionConfig.getActionName()), e);
            throw e;
        } finally {
            stopWatch.stop();
            ActionResponse response = actionConfig.getResponse();
            if (null != response) {
                ((AbstractActionResponse) response).setTakeTime(stopWatch
                        .getTime());
            }
            LOGGER.debug(String.format("<=> invoke api [%s] take time : %sms ",
                    actionConfig.getActionName(), stopWatch.getTime()));
            MDC.remove("action.name");
            MDC.remove("request.id");
        }

    }

}
